package org.wx.thread.unsafe;

import lombok.Data;
import sun.misc.Unsafe;

import java.lang.reflect.Field;

/**
 * @description: unsafe Test
 * @author: wangxun
 * @createDate: 2021/4/14
 * @version: 1.0
 */
public class UnSafeBasicsTest {
    static Unsafe unSafe;
    /**
     *  unSafe 是不提供源码的
     *   private Unsafe() {
     *     }
     *     而且私有构造器
     *     如果想要使用，就得用反射
     */
    public static void main(String[] args)throws Exception {
        final Class<?> unSafeClazz = Class.forName("sun.misc.Unsafe");
        final Field theUnsafe = unSafeClazz.getDeclaredField("theUnsafe");
        theUnsafe.setAccessible(true);
        unSafe= (Unsafe) theUnsafe.get(null);

        final Person wx = new Person();
        wx.setId(11);
        wx.setName("wx");

        final UnSafeBasicsTest unSafeBasicsTest = new UnSafeBasicsTest();
        System.out.println("unsafe 获取到的值"+ unSafeBasicsTest.getIntField(wx, 12L));

        // 将wx 的id修改为22
        unSafeBasicsTest.putIntField(wx,12,22);
        System.out.println("unsafe put之后:"+wx.getId());

    }

    /**
     * 根据对象 获取对应位置的int 属性
     * @param o 对象
     * @param offset int类型在对象中的偏移量
     *               markword 8字节
     *               clazz point 压缩后 4字节
     *
     * @return
     */
    public int getIntField(Object o ,long offset) throws Exception{
        final Field id = Person.class.getDeclaredField("id");
        System.out.println(unSafe.objectFieldOffset(id));

        return unSafe.getInt(o, offset);
    }

    /**
     * 对对象的某个偏移量的int　进行修改
     * @param o 对象
     * @param offset 偏移量
     * @param expect 期望值
     */
    public void putIntField(Object o,long offset,int expect){
        unSafe.putInt(o,offset,expect);
    }

    @Data
    static class Person{
        private int id;
        private String name;

    }


}
